最近對於 GetComponent我想記錄一些使用上的操作,並讓我更熟悉在 Unity 環境中使用。
我們知道在C#宣告物件的時後常會使用 new 加上類別名稱。但在Unity宣告或取得物件的方式會不太相同。
Object本身可以自帶許多Component。我通常會將在環境的Object稱為物件,物件會在Hierarchy內部。
Component則取名為每個物件中的元素,點選物件的時候,就會看到 Inspector 顯示該物件所有的元素。
物件可以包含很多的元素,但是若需要呼叫這些元素就需要有特定物件宣告的方法,在 Unity 中宣告某類別的物件不如同一般C# 的 new 加上類別名稱。反而會有更有效率地以不同方式去實例化元素的內容。基本上我們在Unity 宣告物件有更簡單的方式。
所以接下來會透過不同的實作來使用本身物件的元素,並進行說明。
首先在Hierarchy 左邊新增一個 Empty Component後,接著在右邊 Inspector 中去新增一個 Sprite Renderer 的 Component。(Sprite Renderer 中 Sprite 設定為 Knob)
接下來新增一個 Rigidbody 2D,將Gravity Scale 設定為 0。目的是我們不需要設定重力造成該Circle 向下墜落。
最後結果如下。
我們要去改寫該物件的顏色,這邊新增一個文本在下方的Project 資料夾下,最後拓移到我們 Circle 物件的 Inspector 區域。使其該文本成為我們物件的Component。
這邊撰寫文本上的內容。 每個文本會對應到該物件上 Inspector 上的物件,故注意到當我想要改變本身 Inspector 上物件的內容,比如說這邊要更改該 SpriteRenderer 物件上的顏色,我們必須要讓系統知道是Inspector 上哪一個物件。故需要透過以下的程式碼來取得該 Inspector 中取得特定的物件才能有效的更新物件的顏色。
SpriteRenderer spriter = GetComponent<SpriteRenderer>();
整體程式碼如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeColor : MonoBehaviour
{
private SpriteRenderer spriter;
public Color newColor;
void Start()
{
spriter = GetComponent<SpriteRenderer>();
spriter.color = newColor;
}
}
接下來回到Unity 去設定你想要變更的顏色屬性。
執行該程式碼看有無變化。可以看到執行後由白轉綠。
首先新增一個空白物件 Square,後續新增 Sprite Renderer 、 Rigidbody 2D、Box Collider 2D。(這邊Circle 物件也需要新增 RigidBody) 後續注意到 Sprite Renderer 內部的 Sprite 點選UISprite。 Rigidbody 2D 上的 Gravity Scale 設定為 0 (否則會因為重力而往下掉落)。
為了當物件碰撞的時候能被偵測,故我們將 Rigidbody 2D 上的 IsTrigger 點選起來(請注意務必要有Rigidbody 2D 在該 Circle 與 Square內部)
回到物件 Circle 上也要新增一個 Circle Collider 2D 的元素。(但請注意到當要偵測撞擊時,僅一個物件上的 Collider 元素設定 IsTrigger 即可。
接下來新增一個文本 Square.cs 放置到 Square 物件的 Inspector 上。
點開之前 ChangeColor.cs 的文本。 設定一個方法,最後將我們剛剛更改物件顏色的程式碼放入到我們公用的function, void setNewColor( )中。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ChangeColor : MonoBehaviour
{
private SpriteRenderer spriter;
public Color newColor;
void Start()
{
}
public void setNewColor()
{
spriter = GetComponent<SpriteRenderer>();
spriter.color = newColor;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Square : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collision) {
ChangeColor changeColor = collision.GetComponent<ChangeColor>();
changeColor.setNewColor();
}
}
首先我們將Circle中的 Tag 設定成 Player。
打開 Square.cs 文本上去編寫一段程式。 我們也可以先宣告一個 GameObject,幫我們找尋到該tag 名為 Player 的物件後並存取。接著若 Player 並非為Null的話就使其將ChangeColor 文本在 Circle Inspector 中的 Sprite Renderer 的顏色作變更。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Square : MonoBehaviour
{
private ChangeColor changeCol;
private GameObject player;
void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
if(player != null)
{
changeCol = player.GetComponent<ChangeColor>();
changeCol.setNewColor();
}
}
}
這裡要注意到更改Hierarchy物件的地方,我們將之前的 Square 放置到我們 Circle之 child 下。
我們要在 Square.cs 取得 Circle 中ChangeColor類別內的 Function,注意到我們這邊要取得該Parent 的物件。故需要使用 GetComponentInParent 來取得 Square 上 Circle Parent 文本中的方法。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Square : MonoBehaviour
{
private ChangeColor changeCol;
void Start()
{
changeCol = GetComponentInParent<ChangeColor>();
changeCol.setNewColor();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Square : MonoBehaviour
{
public ChangeColor changeColorObj;
void Start()
{
changeColorObj.setNewColor();
}
}
一開始可能會懷疑為何不需要使用到任何GetComponent類別去獲取該 ChangeColor類別上的物件。是因為這樣宣告的話我們可以透過回到 Unity 中將具有該文本的物件中,拉入到我們 Square 上的 ChangeColor 的物件上。系統會自行地根據該物件的位置進行宣告其類別的物件。 Circle 就是你的物件,而ChangeColor 就是該Circle 物件內的元素 ChangeColor.c文本(腳本)。
這樣就可以使用 Circle 中的 SetNewColor 的方法。